﻿namespace Anley.DomainDrivenDesign.Contract.Helper;

/// <summary>
/// 网络请求帮助类
/// </summary>
public class HttpHelper
    : IHttpHelper
{
    private readonly ILogger _logger;
    private readonly IHttpClientFactory _httpClientFactory;

    public HttpHelper(
        IHttpClientFactory httpClientFactory)
    {
        _logger = LogManager.GetCurrentClassLogger();
        _httpClientFactory = httpClientFactory;
    }

    // GET/JSON请求
    public async Task<TRes?> GetJsonAsync<TRes>(
        string url,
        Dictionary<string, string>? queryParams = null,
        string? name = null)
        where TRes : class
    {
        // 如果有传参，则拼接
        if (queryParams?.Count > 0)
        {
            // 拼接参数
            var queryEnumerable = queryParams
                .Where(p => !string.IsNullOrWhiteSpace(p.Key))
                .Select(p => $"{p.Key}={p.Value}");
            var queryString = string.Join("&", queryEnumerable);
            // 拼接请求地址
            var front = url.Contains("?") ? "&" : "?";
            url = $"{url}{front}{queryString}";
        }
        // 实例化请求
        using var httpClient = string.IsNullOrWhiteSpace(name)
            ? _httpClientFactory.CreateClient()
            : _httpClientFactory.CreateClient(name);
        try
        {
            using var httpResponse = await httpClient.GetAsync(url);
            httpResponse.EnsureSuccessStatusCode();
            var response = await httpResponse.Content.ReadAsStringAsync();
            if (string.IsNullOrWhiteSpace(response))
                return null;
            return JsonConvert.DeserializeObject<TRes>(response);
        }
        catch (Exception ex)
        {
            _logger.Error(ex, "发送HTTP请求时出错");
            return null;
        }
    }

    // POST/JSON请求
    public async Task<TRes?> PostJsonAsync<TRes>(
        string url,
        object? requestParam = null,
        string? name = null)
        where TRes : class
    {
        // 请求内容
        var json = JsonConvert.SerializeObject(requestParam, Formatting.None, new JsonSerializerSettings()
        {
            NullValueHandling = NullValueHandling.Ignore
        });
        var content = new StringContent(json, Encoding.UTF8, AneConsts.JSONContentType);
        // 实例化请求
        using var httpClient = string.IsNullOrWhiteSpace(name)
            ? _httpClientFactory.CreateClient()
            : _httpClientFactory.CreateClient(name);
        try
        {
            using var httpResponse = await httpClient.PostAsync(url, content);
            httpResponse.EnsureSuccessStatusCode();
            var response = await httpResponse.Content.ReadAsStringAsync();
            if (string.IsNullOrWhiteSpace(response))
                return null;
            return JsonConvert.DeserializeObject<TRes>(response);
        }
        catch (Exception ex)
        {
            _logger.Error(ex, "发送HTTP请求时出错");
            return null;
        }
    }

    // POST/JSON请求
    public Task<TRes?> PostJsonAsync<TRes, TReq>(
        string url,
        TReq requestParam,
        string? name = null)
        where TRes : class
    {
        return PostJsonAsync<TRes>(url, requestParam, name);
    }

    // POST/FORM请求
    public async Task<string?> PostFormAsync(
        string url,
        Dictionary<string, string>? formData = null,
        string? name = null)
    {
        // 请求内容
        var content = formData == null || formData.Count == 0
            ? null
            : new FormUrlEncodedContent(formData);
        // 实例化请求
        using var httpClient = string.IsNullOrWhiteSpace(name)
            ? _httpClientFactory.CreateClient()
            : _httpClientFactory.CreateClient(name);
        try
        {
            using var httpResponse = await httpClient.PostAsync(url, content);
            httpResponse.EnsureSuccessStatusCode();
            return await httpResponse.Content.ReadAsStringAsync();
        }
        catch (Exception ex)
        {
            _logger.Error(ex, "发送HTTP请求时出错");
            return null;
        }
    }

    // POST/FORM请求
    public async Task<string?> PostFormAsync(
        string url,
        Dictionary<string, string>? formData = null,
        Dictionary<string, IFormFile>? fileData = null,
        string? name = null)
    {
        MultipartFormDataContent? content = null;
        // 添加参数
        if (formData?.Count > 0)
        {
            if (content == null)
                content = new MultipartFormDataContent();
            foreach (var field in formData)
                content.Add(new StringContent(field.Value), field.Key);
        }
        // 添加文件
        if (fileData?.Count > 0)
        {
            if (content == null)
                content = new MultipartFormDataContent();
            foreach (var field in fileData)
            {
                var fileStream = field.Value.OpenReadStream();
                var fileContent = new StreamContent(fileStream);
                fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse(field.Value.ContentType);
                content.Add(fileContent, field.Key, field.Value.FileName);
            }
        }
        // 实例化请求
        using var httpClient = string.IsNullOrWhiteSpace(name)
            ? _httpClientFactory.CreateClient()
            : _httpClientFactory.CreateClient(name);
        try
        {
            using var httpResponse = await httpClient.PostAsync(url, content);
            httpResponse.EnsureSuccessStatusCode();
            return await httpResponse.Content.ReadAsStringAsync();
        }
        catch (Exception ex)
        {
            _logger.Error(ex, "发送HTTP请求时出错");
            return null;
        }
    }
}